package com.xiaoq.helper.endpoint;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.highlight.HighlightField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaoq.ESIndexNameProperties;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.helper.entity.HelperEntity;
import com.xiaoq.helper.service.IHelperServcie;
import com.xiaoq.helper.vo.HelperVo;
import com.xiaoq.vo.PagingVo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

@RestController
@RequestMapping(value = "/api/v1/helper")
@Api(tags={"帮助中心相关Api"})
public class HelperEndpoint {
	
	@Autowired
	private IHelperServcie helpSer;
	
	@Autowired
	private IdGenerator idGenerator;
	
	private static final ObjectMapper MAPPER = new ObjectMapper();
	
	@Autowired
	private Client client;
	
	
	@Autowired
	private ESIndexNameProperties indexNameProperties;
	
	@Autowired
	private ElasticsearchTemplate template;
	
	private class HelperGenericListResponse extends GenericListResponse<HelperVo> {}
	
	private static final Logger LOG = LoggerFactory.getLogger(HelperEndpoint.class);
	
	@ApiOperation(value = "获取功能列表", notes = "获取功能列表")
	@ApiResponses({ @ApiResponse(code = 200, response = HelperGenericListResponse.class, message = "获取功能列表") })
	@GetMapping(value = "", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> findHelper(HttpServletRequest request) {
		List<HelperEntity> helpers = helpSer.findHelper();
		List<HelperVo> helpVos = new ArrayList<>();
		HelperVo helperVo = null;
		for(HelperEntity helper:helpers){
			helperVo = new HelperVo();
			BeanUtils.copyProperties(helper, helperVo);
			helpVos.add(helperVo);
		}
		return HelperGenericListResponse.listNoCount(helpVos);
		
	}
	
	@ApiOperation(value = "对接运营后端", notes = "对接运营后端")
	@ApiResponses({ @ApiResponse(code = 200, response = HelperGenericListResponse.class, message = "对接运营后端") })
	@PostMapping(value = "", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> addHelper(@RequestBody HelperVo helper) {
		HelperEntity help = new HelperEntity();
		BeanUtils.copyProperties(helper, help);
		help.setId(idGenerator.nextId());
		helpSer.save(help);
		return GenericResponse.ok();
		
	}
	
	@ApiOperation(value = "搜索问题", notes = "搜索问题")
	@ApiResponses({ @ApiResponse(code = 200, response = HelperGenericListResponse.class, message = "搜索问题") })
	@GetMapping(value = "/query", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> searchHelper(@RequestParam(value="question",required=true)@ApiParam(value="问题",required=true)String question) {
		PagingVo pvo = new PagingVo();
		pvo.setPn(1);
		pvo.setPs(10);
		List<HelperEntity> helpers = findHelperFromESByQuestion(question, pvo);
//		List<HelperEntity> helpers = helpSer.findByQuery(question);
		List<HelperVo> helpVos = new ArrayList<>();
		HelperVo helperVo = null;
		for(HelperEntity helper:helpers){
			helperVo = new HelperVo();
			BeanUtils.copyProperties(helper, helperVo);
			helpVos.add(helperVo);
		}
		return HelperGenericListResponse.listNoCount(helpVos);
		
	}
	
	@ApiOperation(value = "测试搜索全部问题", notes = "测试搜索全部问题")
	@ApiResponses({ @ApiResponse(code = 200, response = HelperGenericListResponse.class, message = "测试搜索全部问题") })
	@GetMapping(value = "/test", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> searchHelpertest(@RequestParam(value="question",required=true)@ApiParam(value="问题",required=true)String question) {
		SearchRequestBuilder searchRequestBuilder = client
				.prepareSearch("titan_online").setTypes("helper");
		 String response = searchRequestBuilder
		            .execute()
		            .actionGet()
		            .toString();
		 System.out.println(response);
		return GenericDataResponse.okWithData(response);
		
	}
	
	public List<HelperEntity> findHelperFromESByQuestion(String query,PagingVo pagingVo){
		 List<HelperEntity> helpers = new ArrayList<>();
		 if(StringUtils.isBlank(query)){
				return helpers;
			}
		 SearchRequestBuilder searchRequestBuilder = client
					.prepareSearch(indexNameProperties.getSitesIndexName());
		 searchRequestBuilder.setTypes("helper");
		 searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		 QueryBuilder queryBuilder = QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("question", query)
					.fuzziness(Fuzziness.AUTO).prefixLength(3).maxExpansions(10).boost(0.98f));
		 queryBuilder = QueryBuilders.queryStringQuery(query).defaultField("question");
		 
		 searchRequestBuilder.setQuery(queryBuilder);
			searchRequestBuilder.setFrom(pagingVo.getPageOffset()).setSize(pagingVo.getPs());
			searchRequestBuilder.setExplain(false);
//			https://www.cnblogs.com/dennisit/p/3363851.html
//			searchRequestBuilder.addHighlightedField("question");
//		    searchRequestBuilder.setHighlighterPreTags("<span>");
//		    searchRequestBuilder.setHighlighterPostTags("</span>");
			SearchResponse response = searchRequestBuilder.execute().actionGet();
			
			SearchHits searchHits = response.getHits();
			SearchHit[] hits = searchHits.getHits();
			for (int i = 0; i < hits.length; i++) {
				SearchHit hit = hits[i];
				String json = hit.getSourceAsString();

				HelperEntity help;
				try {
					help = JSONObject.parseObject(json, HelperEntity.class);
					Map<String, HighlightField> result = hit.highlightFields();
//					HighlightField titleField = result.get("question"); 
//					Text[] titleTexts =  titleField.fragments(); 
//					String question = help.getQuestion();
//					for(Text text : titleTexts){    
//						question += text;  
//		            }
//					help.setQuestion(question);
					help.setId(hit.getId());
					helpers.add(help);
				} catch (Exception e) {
					LOG.error(e.getMessage(), e);
				}
			}

			return helpers;
		 
	 }

}
